package com.xiayuanxing.arithmetic.DataStructures.Stack;

/**
 * @program: arithmetic
 * @description: 栈模拟计算器
 * @author: xia yuan xing
 * @create: 2021-09-07 11:50
 */
public class Calculator {
    public static void main(String[] args) {

        //定义一个表达式
        String expression = "10-2*6+2";

        //创建两个栈，一个数栈一个符号栈
        //数栈
        ArrayStack numberStack = new ArrayStack(10);
        //符号栈
        ArrayStack operStack = new ArrayStack(10);

        //定义相关的变量
        int index = 0;
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' ';
        //用于拼接中位数
        String keepNum = "";

        //开始while循环，扫描expression
        while (true){
            //依次拿到表达式的每一个字符
            ch = expression.substring(index,index+1).charAt(0);
            //判断ch是数字或者字符，不同的东西不同处理
            if (operStack.isOper(ch)){
                if (!operStack.isEmpty()){
                    //如果符号栈有操作符，就进行比较，如果当前的操作符的优先级小于或者
                    //或者等于栈中的操作符，就需要从数栈中pop住两个数
                    //在从符号栈中pop出一个符号，都进行运算，将得到结果，入数栈，然后将当前的操作符入符号栈
                    if (operStack.priority(ch) <= operStack.priority(operStack.peek())){
                        num1 = numberStack.pop();
                        num2 = numberStack.pop();
                        oper = operStack.pop();
                        res = numberStack.cal(num1,num2,oper);
                        //把运算的结果入数栈
                        numberStack.push(res);
                        //将当前的操作符入符号栈
                        operStack.push(ch);
                    }else {
                        //如果当前的操作符的优先级大于栈中的操作符，就直接入符号栈
                        operStack.push(ch);
                    }
                }else {
                    //表示符号栈为空了，直接将符号入符号栈
                    operStack.push(ch);
                }
            }else {
                //处理多位数
                keepNum += ch;

                if (index == expression.length() -1){
                    numberStack.push(Integer.parseInt(keepNum));
                }else {
                    //判断下一个字符是否是数字，是数字继续扫描，是符号的话就入栈
                    if (operStack.isOper(expression.substring(index+1,index+2).charAt(0))){
                        numberStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            }
            //让index + 1 ,并判断是否扫描到expression最后
            index ++;
            if (index >=expression.length()){
                break;
            }
        }

        //表达式扫描完毕，顺序的从数栈和符号栈中pop出相应的数和符号并运行
        while (true){
            //如果符号栈为空，则计算到最后的结果，数栈中只有一个数字（结果）
            if(operStack.isEmpty()){
                break;
            }
            num1 = numberStack.pop();
            num2 = numberStack.pop();
            oper = operStack.pop();
            res = numberStack.cal(num1,num2,oper);
            //把运算的结果入数栈
            numberStack.push(res);
        }

        System.out.printf("%s = %d",expression,numberStack.pop());



    }
}

